package edu.cornell.cs.lsi.projone.service;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.LogFactoryImpl;

import edu.cornell.cs.lsi.projone.common.LSIException;
import edu.cornell.cs.lsi.projone.common.util.AppUtil;
import edu.cornell.cs.lsi.projone.model.ServerData;

/**
 * @author poornima
 * 
 */
public class UDPService {

	// private static DatagramSocket socket;

	private final static Log LOGGER = LogFactoryImpl.getLog(UDPService.class);

	public static void sendPacket(String message, ServerData destServer)
			throws LSIException, UnknownHostException {
		LOGGER.info("sendPacket(): starts-------------------------------");
		if (message == null || StringUtils.isEmpty(message)
				|| destServer == null) {
			LOGGER.error("Incoming parameters are empty");
			throw new LSIException("SendPacket: incoming parameters are empty");
		}
		try {
			//DatagramSocket s = new DatagramSocket();
			DatagramSocket s = AppUtil.getDatagramSkt();
			
			LOGGER.info("sendPacket(): --------- IP "
					+ destServer.getIpHostName());
			LOGGER.info("sendPacket(): --------- port " + destServer.getPort());
			LOGGER.info("sendPacket(): --------- message------------------------- "
					+ message);
			
			byte messg[] = message.getBytes();
			InetAddress destAddr = InetAddress.getByName(destServer
					.getIpHostName());
			DatagramPacket out = new DatagramPacket(messg, messg.length,
					destAddr, destServer.getPort());
			s.send(out);
		} catch (SocketException e) {
			e.printStackTrace();
			throw new LSIException(e, "Error while creating the socket object");
		} catch (UnknownHostException e) {
			e.printStackTrace();
			throw new LSIException(e, "Error while sending the packet");
		} catch (IOException e) {
			e.printStackTrace();
			throw new LSIException(e,
					"Error while sending the packet, IO error");
		}
		LOGGER.info("sendPacket(): ends-------------------");
	}

	public static String recvPacket(int port, int timeout) throws LSIException,
			SocketTimeoutException {
		LOGGER.info("recvPacket(): starts-------------------");
		byte messg[] = new byte[1024];
		DatagramPacket pkt = new DatagramPacket(messg, messg.length);

		String result = "";
		try {
			// DatagramSocket socket;
			// socket = new DatagramSocket(port);
			// DatagramSocket rpcSocket = new DatagramSocket(AppUtil.getPort());
			DatagramSocket rpcSocket = new DatagramSocket();
			// int portNo = rpcSocket.getLocalPort();
			// LOGGER.info("  receiev port   " + AppUtil.getPort());
			// socket = new DatagramSocket(portNo);
			LOGGER.info("  &&&& timeout   " + timeout);

			rpcSocket.setSoTimeout(timeout);
			rpcSocket.receive(pkt);
			result = pkt.getData().toString();

			rpcSocket.close();
			// rpcSocket.close();
		} catch (IOException e) {
			// Have to check for timeouts here
			e.printStackTrace();
			throw new LSIException(e, "Error while receiving the packet.");
		}
		LOGGER.info("recvPacket(): ends-------------------");
		return result;
	}
}